跳到内容
+

覆盖组件结构

了解如何覆盖 Joy UI 组件的默认 DOM 结构。

Joy UI 组件旨在适应最广泛的用例,但您有时可能需要更改组件结构在 DOM 中的呈现方式。

为了理解如何做到这一点,拥有组件的准确心智模型会有所帮助。

心智模型

组件的结构由填充该组件**插槽**的元素决定。插槽最常由 HTML 标签填充,但也可能由 React 组件填充。

所有组件都包含一个**根插槽**,用于定义它们在 DOM 树中的主要节点;更复杂的组件还包含以它们所代表的元素命名的其他**内部插槽**。

所有非实用程序 Joy UI 组件都接受两个属性来覆盖其渲染的 HTML 结构

  • component——覆盖根插槽
  • slots——替换任何内部插槽(如果存在)以及根插槽

此外,您可以使用 slotProps 将自定义属性传递给内部插槽。

根插槽

根插槽代表组件的最外层元素。它由一个带有适当 HTML 元素的样式化组件填充。

例如,Button 的根插槽是一个 <button> 元素。此组件有一个根插槽;更复杂的组件可能有额外的内部插槽

component 属性

使用 component 属性来覆盖组件的根插槽。下面的演示展示了如何将 Button 的 <button> 标签替换为 <a> 以创建一个链接按钮

按 `Enter` 开始编辑

内部插槽

复杂组件由一个或多个内部插槽以及根插槽组成。这些插槽通常(但不一定)嵌套在根插槽内。

例如,Autocomplete 由一个根 <div> 组成,该根 <div> 包含多个以它们所代表的元素命名的内部插槽:input、startDecorator、endDecorator、clearIndicator、popupIndicator 等等。

slots 属性

使用 slots 属性来替换组件的内部插槽。下面的示例展示了如何替换 Autocomplete 组件中的 listbox 插槽以删除弹出功能

按 `Enter` 开始编辑

slotProps 属性

`slotProps` 属性是一个对象,其中包含组件内所有插槽的属性。您可以使用它来定义要传递给组件内部插槽的其他自定义属性。

例如,下面的代码片段展示了如何向 Autocomplete 组件的 listbox 插槽添加自定义 data-testid

<Autocomplete slotProps={{ listbox: { 'data-testid': 'my-listbox' } }} />

放置在主组件上的所有其他属性也会传播到根插槽中(就像它们放置在 slotProps.root 中一样)。这两个示例是等效的

<Autocomplete id="badge1">
<Autocomplete slotProps={{ root: { id: 'badge1' } }}>

最佳实践

使用 componentslotProps.{slot}.component 属性通过保留插槽的样式来覆盖元素。

使用 slots 属性将插槽的样式和功能替换为您自定义的组件。

使用 component 进行覆盖允许您将该元素的属性直接应用于根元素。例如,如果您使用 <li> 标签覆盖 Button 的根元素,则可以直接将 <li> 属性 value 添加到组件。如果您对 slots.root 执行相同的操作,则需要将此属性放在 slotProps.root 对象上,以避免 TypeScript 错误。

在覆盖更复杂组件的插槽时,请注意您渲染的 DOM 结构。如果您偏离默认结构太远,很容易破坏语义化和可访问 HTML 的规则——例如,无意中将块级元素嵌套在内联元素中。Joy UI 组件会自动纠正语义上不正确的 HTML——有关详细信息,请参阅自动调整